package com.xiaobai.units;

import com.alibaba.fastjson.JSONObject;
import com.xiaobai.config.MyJSESSIONIdManager;
import com.xiaobai.exception.LoginException;
import com.xiaobai.exception.RequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.util.Base64Util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: 小白白
 * @create: 2021-08-31
 **/

@Slf4j
public class HttpUnits_V2 {

    // 登录
    private static String loginUrl = "https://jwxt.gdupt.edu.cn/login!doLogin.action";

    //

    public static CloseableHttpClient httpclient = HttpClients.createDefault();

    /**
     * 登录,返回 jsessionId
     */
    public static String gyLogin(String username,String password) {
        HttpPost httpPost = new HttpPost(loginUrl);
        List<NameValuePair> list = new ArrayList<>();
        list.add(new BasicNameValuePair("account", username));
        list.add(new BasicNameValuePair("pwd", Base64Util.encode(password)));
        UrlEncodedFormEntity urlEncodedFormEntity = null;
        try {
            urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        httpPost.setEntity(urlEncodedFormEntity);
        String jsessionId;
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            jsessionId = response.getLastHeader("Set-Cookie").getElements()[0].getValue();
            httpPost.setHeader("Cookie","JSESSIONID=" + jsessionId);

            // 必须要close,不然下面执行不了,因为路由限制
            response.close();

            response = httpclient.execute(httpPost);
            String content = EntityUtils.toString(response.getEntity());
            JSONObject jsonObject = JSONObject.parseObject(content);
            if (content.contains("不正确")) {
                throw new LoginException(jsonObject.getString("msg"));
            }
            if (content.contains("解锁")) {
                throw new LoginException("密码错误过多,请稍后再试");
            }
            if (jsonObject.getString("status").equals("n")) {
                log.error("登录时发生未知错误"+content);
                throw new LoginException("登陆时发生未知错误");
            }
            MyJSESSIONIdManager.set(jsessionId);
        } catch (IOException e) {
            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            if (hour >= 23 || hour <= 6) {
                // 凌晨就提示教务关网了
                log.error(e.getMessage());
                throw new LoginException("教务官网休息了");
            } else{
                e.printStackTrace();
                throw new LoginException("未知错误,请联系admin");
            }
        }finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return jsessionId;
    }

    /**
     * gy通用get
     */
    public static String commonGyGet(String url, Map<String,String> paramsMap, String jsessionId) {
        String JSESSIONID = jsessionId != null ? jsessionId : MyJSESSIONIdManager.get();
        URI uri = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            if (paramsMap != null) {
                for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                    uriBuilder.addParameter(entry.getKey(),entry.getValue());
                }
            }
            uri = uriBuilder.build();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        HttpGet httpGet = new HttpGet(uri);
        httpGet.setHeader("Cookie", "JSESSIONID=" + JSESSIONID);
        String result = null;
        try (CloseableHttpResponse response = httpclient.execute(httpGet)){
            result = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RequestException("请求官网时发生错误");
        }
        return result;
    }

    /**
     * gy通用post
     */
    public static String commonGyPost(String url, Map<String,Object> paramsMap, String jsessionId) {
        String JSESSIONID = jsessionId != null ? jsessionId : MyJSESSIONIdManager.get();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> list = new ArrayList<>();
        if (paramsMap != null) {
            for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(),entry.getValue().toString()));
            }
        }
        UrlEncodedFormEntity urlEncodedFormEntity = null;
        try {
            urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        httpPost.setEntity(urlEncodedFormEntity);
        httpPost.setHeader("Cookie", "JSESSIONID=" + JSESSIONID);
        String result = null;
        try (CloseableHttpResponse httpResponse = httpclient.execute(httpPost);){
            result = EntityUtils.toString(httpResponse.getEntity());
        } catch (IOException e) {
            log.error("error of get request, url:{}, params:{}, err:{}", url, paramsMap, e);
            throw new RequestException("请求官网时发生错误");
        }
        return result;
    }

    /**
     * 获取响应状态码
     */
    public static Integer getStatus(String url) throws IOException {
        HttpHead httpPost = new HttpHead(url);
        Integer result;
        try (CloseableHttpResponse httpResponse = httpclient.execute(httpPost)){
            result = httpResponse.getStatusLine().getStatusCode();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RequestException("请求" + url + "时发生错误");
        }
        return result;
    }

    public static void op(long s) {
        System.out.println(System.currentTimeMillis() - s);
    }

    public static void main(String[] args) throws IOException {
//        Integer status = getStatus("http://image.xiaobaibai.work/freeClassroom/2021-11-26.json");
//        System.out.println(status);
        long s1 = System.currentTimeMillis();
        CloseableHttpClient client1 = HttpClients.createDefault();
        op(s1);
        long s2 = System.currentTimeMillis();
        client1.execute(new HttpGet("http://baidu.com"));
        op(s2);
        long s3 = System.currentTimeMillis();
        CloseableHttpClient client2 = HttpClients.createDefault();
        op(s3);
        long s4 = System.currentTimeMillis();
        client2.execute(new HttpGet("http://baidu.com"));
        op(s4);
        long s5 = System.currentTimeMillis();
        client1.execute(new HttpGet("http://baidu.com"));
        op(s5);
    }

}
